package com.learn.security.web.security;

import com.learn.security.domain.SysPermission;
import com.learn.security.service.ISysPermissionService;
import com.learn.security.service.ISysRoleService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.PermissionEvaluator;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Component;
import org.thymeleaf.util.StringUtils;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Objects;

/**
 * @auther liuhw
 * @date 2020/3/22 21:32
 * @description:
 * @since 1.0
 **/
@Slf4j
@Component
public class AdminPermissionEvaluator implements PermissionEvaluator {
    @Autowired
    private ISysPermissionService permissionService;

    @Autowired
    private ISysRoleService roleService;

    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {
        // 获取UserDetails.loadByUserName 结果
        UserDetails user = userDetailsService.loadUserByUsername(String.valueOf(authentication.getPrincipal()));
        // 获取user的角色
        @SuppressWarnings({"unchecked"})
        Collection<GrantedAuthority> authorities = (Collection<GrantedAuthority>) user.getAuthorities();

        // 遍历所有角色
        for (GrantedAuthority authority : authorities) {
            String roleName = authority.getAuthority();
            Integer roleId = roleService.getByName(roleName).getId();

            List<SysPermission> permissions = permissionService.listByRoleId(roleId);
            if (log.isInfoEnabled()) {
                log.info("角色 {} 具有权限 [{}]", roleName, StringUtils.join(permissions, ','));
            }

            for (SysPermission sysPermission : permissions) {
                // 获取权限集
                List permissionds = sysPermission.getPermissions();
                // 如果权限和url符合 返回true
                if (Objects.equals(targetDomainObject, sysPermission.getUrl()) && permissionds.contains(permission)) {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) {
        return false;
    }
}
